<template>
  <div class="page">
    <header class="header">
      <h1>MateChat + DevUI：AI 编程智能答疑助手</h1>
      <!-- 这是DevUI 按钮 -->
      <d-button type="primary" @click="resetChat">清空对话</d-button>
    </header>

    <!-- 核心聊天区域：使用 MateChat 提供的布局组件 -->
    <McLayout class="chat-container">
      <McHeader :title="'智能问答 Demo'" :logoImg="logo">
        <template #operationArea>
          <div class="operations">
            <span>已接入deepseek AI 大模型</span>
          </div>
        </template>
      </McHeader>

      <!-- 内容区：消息列表 -->
      <McLayoutContent class="chat-content">
        <template v-for="(msg, idx) in messages" :key="idx">
          <!-- 用户消息，右对齐 -->
          <McBubble
            v-if="msg.from === 'user'"
            :content="msg.content"
            align="right"
            :avatarConfig="{ name: '我' }"
          />
          <!-- 助手消息，左对齐，支持 Markdown -->
          <McBubble
            v-else
            :avatarConfig="{ name: 'Bot' }"
          >
            <div class="markdown-content" v-html="renderMarkdown(msg.content)"></div>
          </McBubble>
        </template>
      </McLayoutContent>

      <!-- 底部输入区 -->
      <McLayoutSender>
        <McInput
          :value="inputValue"
          :maxLength="1000"
          placeholder="请输入你的问题，比如：什么是 token？"
          @change="onChange"
          @submit="onSubmit"
        />
      </McLayoutSender>
    </McLayout>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import OpenAI from 'openai'
import { marked } from 'marked'

// 配置 marked
marked.setOptions({
  breaks: true, // 支持换行
  gfm: true, // 支持 GitHub 风格的 Markdown
})

// 渲染 Markdown 内容
const renderMarkdown = (content: string): string => {
  if (!content) return ''
  return marked.parse(content) as string
}

const logo = 'https://matechat.gitcode.com/logo.svg' // 官方 logo 地址

// 初始化 AI 客户端
const client = ref<OpenAI>()

// DeepSeek 配置
client.value = new OpenAI({
  apiKey: import.meta.env.VITE_DEEPSEEK_API_KEY, // 从环境变量读取 APIKey
  baseURL: import.meta.env.VITE_DEEPSEEK_BASE_URL, // 从环境变量读取 API 地址
  dangerouslyAllowBrowser: true, // 浏览器环境使用需要开启
})

// 输入框内容
const inputValue = ref('')

// 消息类型定义
interface Message {
  from: 'user' | 'assistant'
  content: string
  avatarConfig?: { name: string }
  id?: string
  loading?: boolean
}

// 消息列表
const messages = ref<Message[]>([
  {
    from: 'assistant',
    content: '你好，我是deepseek AI 助手，有什么可以帮助你的吗？',
    avatarConfig: { name: 'Bot' },
  },
])

// 输入框变化
const onChange = (val: string) => {
  inputValue.value = val
}

// 调用 DeepSeek API（流式返回）
const fetchData = async (ques: string) => {
  // 添加一个加载中的助手消息
  messages.value.push({
    from: 'assistant',
    content: '',
    avatarConfig: { name: 'Bot' },
    id: '',
    loading: true,
  })

  try {
    const completion = await client.value!.chat.completions.create({
      model: 'deepseek-chat', // DeepSeek 模型
      messages: [{ role: 'user', content: ques }],
      stream: true, // 开启流式返回
    })

    // 获取当前消息索引
    const currentMsgIndex = messages.value.length - 1

    // 关闭 loading 状态
    if (messages.value[currentMsgIndex]) {
      messages.value[currentMsgIndex].loading = false
    }

    // 逐步接收流式返回的内容
    for await (const chunk of completion) {
      const content = chunk.choices[0]?.delta?.content || ''
      const chatId = chunk.id
      if (messages.value[currentMsgIndex]) {
        messages.value[currentMsgIndex].content += content
        messages.value[currentMsgIndex].id = chatId
      }
    }
  } catch (error: any) {
    // 错误处理
    const currentMsgIndex = messages.value.length - 1
    if (messages.value[currentMsgIndex]) {
      messages.value[currentMsgIndex].loading = false

      // 显示详细错误信息
      let errorMsg = '抱歉，请求失败了。'
      if (error.message) {
        errorMsg += `\n错误信息: ${error.message}`
      }
      if (error.status) {
        errorMsg += `\n状态码: ${error.status}`
      }

      messages.value[currentMsgIndex].content = errorMsg
    }
    console.error('DeepSeek API 调用失败:', error)
  }
}

// 发送消息
const onSubmit = (val?: string) => {
  const text = (val ?? inputValue.value).trim()
  if (!text) return

  // 清空输入框
  inputValue.value = ''

  // 先把用户消息 push 进去
  messages.value.push({
    from: 'user',
    content: text,
    avatarConfig: { name: '我' },
  })

  // 调用 DeepSeek API
  fetchData(text)
}

// 清空对话
const resetChat = () => {
  messages.value = [
    {
      from: 'assistant',
      content: '对话已重置，可以重新开始问问题啦～',
      avatarConfig: { name: 'Bot' },
    },
  ]
}
</script>

<style scoped>
.page {
  min-height: 100vh;
  background: #f5f7fa;
  padding: 24px;
  box-sizing: border-box;
}

.header {
  max-width: 960px;
  margin: 0 auto 16px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.header h1 {
  margin: 0;
  font-size: 20px;
}

.header p {
  margin: 0;
  color: #666;
  font-size: 14px;
  flex: 1;
}

.chat-container {
  max-width: 960px;
  margin: 0 auto;
  height: calc(100vh - 120px);
  background: #fff;
  border-radius: 16px;
  padding: 16px;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
}

.chat-content {
  flex: 1;
  overflow-y: auto;
  padding: 8px 0;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.operations {
  font-size: 12px;
  color: #666;
}

/* Markdown 内容样式 */
.markdown-content {
  line-height: 1.6;
}

.markdown-content :deep(h1),
.markdown-content :deep(h2),
.markdown-content :deep(h3),
.markdown-content :deep(h4),
.markdown-content :deep(h5),
.markdown-content :deep(h6) {
  margin: 16px 0 8px 0;
  font-weight: 600;
}

.markdown-content :deep(h1) {
  font-size: 1.5em;
}

.markdown-content :deep(h2) {
  font-size: 1.3em;
}

.markdown-content :deep(h3) {
  font-size: 1.1em;
}

.markdown-content :deep(p) {
  margin: 8px 0;
}

.markdown-content :deep(ul),
.markdown-content :deep(ol) {
  margin: 8px 0;
  padding-left: 24px;
}

.markdown-content :deep(li) {
  margin: 4px 0;
}

.markdown-content :deep(code) {
  background: #f0f0f0;
  padding: 2px 6px;
  border-radius: 4px;
  font-family: 'Consolas', 'Monaco', monospace;
  font-size: 0.9em;
}

.markdown-content :deep(pre) {
  background: #f5f5f5;
  padding: 12px;
  border-radius: 8px;
  overflow-x: auto;
  margin: 8px 0;
}

.markdown-content :deep(pre code) {
  background: transparent;
  padding: 0;
}

.markdown-content :deep(blockquote) {
  border-left: 4px solid #ddd;
  margin: 8px 0;
  padding-left: 12px;
  color: #666;
}

.markdown-content :deep(hr) {
  border: none;
  border-top: 1px solid #eee;
  margin: 16px 0;
}

.markdown-content :deep(a) {
  color: #1890ff;
  text-decoration: none;
}

.markdown-content :deep(a:hover) {
  text-decoration: underline;
}

.markdown-content :deep(table) {
  border-collapse: collapse;
  width: 100%;
  margin: 8px 0;
}

.markdown-content :deep(th),
.markdown-content :deep(td) {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

.markdown-content :deep(th) {
  background: #f5f5f5;
  font-weight: 600;
}

.markdown-content :deep(strong) {
  font-weight: 600;
}
</style>
